using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.ConnectionEngine.Common
{
    /// <summary>
    /// This class is to handle exceptional events which arise from the operation
    /// of the adapter component implemented for a connected system or within the Routing Service
    /// </summary>
    public class SystemAdapterException : System.Exception
    {
        #region privateAttributes
        private SystemAdapterExceptionCause cause;//the culprit
        private Exception original;//the first exception if there was one
        #endregion
        
        #region publicAttributes
        public SystemAdapterExceptionCause Cause//the culprit
        { get { return this.cause; } }
        public Exception Original//the culprit
        { get { return this.original; } }
        #endregion

        public SystemAdapterException(SystemAdapterExceptionCause cause, string message, Exception original):base(message)
        {
            this.cause = cause;
            this.original = original;
        }

        //public SystemAdapterException(SystemAdapterExceptionCause cause, string message, Exception original, ref PnPMessageHeader header):base(message)
        //{
        //    this.cause = cause;
        //    this.original = original;
        //    header.Status.Code = cause.ToString();
        //    header.Status.Description = message + "\r\n" + SystemAdapterException.GetExceptionDescription(cause);
        //}

        public static string GetExceptionDescription(SystemAdapterExceptionCause cause)
        {
            StringBuilder sb = new StringBuilder();
            switch (cause)
            {
                case SystemAdapterExceptionCause.ApplicationAdapterInterface:
                    {
                        sb.Append("There was a problem between the adapter and its associated connected system.");
                        break;
                    }
                case SystemAdapterExceptionCause.SourceAndDestinationNotInTheSamePool :
                    {
                        sb.Append("The source and destination service providers are not in the same pool.");
                        break;
                    }
                case SystemAdapterExceptionCause.ConnectingToInternet:
                    {
                        sb.Append("There was a problem connecting to the internet.");
                        break;
                    }
                case SystemAdapterExceptionCause.CreatingPnPMsg:
                    {
                        sb.Append("There was a problem creating a Connection Engine Message.");
                        break;
                    }
                case SystemAdapterExceptionCause.ErrorDuringHsdValidationOfMsg:
                    {
                        sb.Append("There was an error during validation of a message supplied by the Service Provider Register.");
                        break;
                    }
                case SystemAdapterExceptionCause.GeneralXml:
                    {
                        sb.Append("There was a general XML problem.");
                        break;
                    }
                case SystemAdapterExceptionCause.Hl7PlayloadCreation:
                    {
                        sb.Append("There was a problem during the creation of the Connection Engine Message payload.");
                        break;
                    }
                case SystemAdapterExceptionCause.Hl7RequestValidation:
                    {
                        sb.Append("There was a problem with the validation of the Connection Engine Message request.");
                        break;
                    }
                case SystemAdapterExceptionCause.Hl7ResponseValidation:
                    {
                        sb.Append("There was a problem with the validation of the Connection Engine Message response.");
                        break;
                    }
                case SystemAdapterExceptionCause.MessageHasNotValidDestination:
                    {
                        sb.Append("The message could not be sent to source as the destination was not valid or could not be found in the pool.");
                        break;
                    }
                case SystemAdapterExceptionCause.Ok:
                    {
                        sb.Append("Status OK");
                        break;
                    }
                case SystemAdapterExceptionCause.PayloadContentNotValid:
                    {
                        sb.Append("The content of the Connection Engine Message payload is not valid.");
                        break;
                    }
                case SystemAdapterExceptionCause.PayloadDecryption:
                    {
                        sb.Append("There was a problem with the decryption of the Connection Engine Message payload.");
                        break;
                    }
                case SystemAdapterExceptionCause.PayloadEncryption:
                    {
                        sb.Append("There was a problem with the encryption of the Connection Engine Message payload");
                        break;
                    }
                case SystemAdapterExceptionCause.PayloadFormatNotValid:
                    {
                        sb.Append("There was a problem with the format of the Connection Engine Message payload.");
                        break;
                    }
                default:
                    sb.Append("Unknown");
                    break;
            }
            return sb.ToString();
        }
        public static int GetPriority(SystemAdapterExceptionCause cause)
        {
            int ret = -1;
            switch (cause)
            {
                case SystemAdapterExceptionCause.ApplicationAdapterInterface:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.SourceAndDestinationNotInTheSamePool:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.ConnectingToInternet:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.CreatingPnPMsg:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.ErrorDuringHsdValidationOfMsg:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.GeneralXml:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.Hl7PlayloadCreation:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.Hl7RequestValidation:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.Hl7ResponseValidation:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.MessageHasNotValidDestination:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.Ok:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.PayloadContentNotValid:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.PayloadDecryption:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.PayloadEncryption:
                    {
                        ret = 1;
                        break;
                    }
                case SystemAdapterExceptionCause.PayloadFormatNotValid:
                    {
                        ret = 1;
                        break;
                    }
                default:

                    break;
            }
            return ret;
        }
    }

    /// <summary>
    /// The description of each enumerated member
    /// should match the description provided in the latest version of the HCE Architect and Design document.
    /// This enumerated type is used to describe the type of exception thrown by an adapter
    /// </summary>
    public enum SystemAdapterExceptionCause
    {
        Ok = 0,
        SourceAndDestinationNotInTheSamePool = 3,
        MessageHasNotValidDestination = 4,
        PayloadFormatNotValid = 5,
        PayloadContentNotValid = 6,
        PayloadDecryption = 7,
        PayloadEncryption = 8,
        Hl7PlayloadCreation = 9,
        ConnectingToInternet = 10,
        CreatingPnPMsg = 11,
        Hl7ResponseValidation = 12,
        Hl7RequestValidation = 13,
        ApplicationAdapterInterface  = 14,
        GeneralXml = 19,
        ErrorDuringHsdValidationOfMsg = 20,
        MessageAssembly = 21,
        MessageDisassembly = 22,
        Unknown = 99,
        Test = 9999
    }
}
